package cn.bonoon.kernel.support.searcher;

import java.util.List;

import cn.bonoon.kernel.support.models.AjaxNode;
import cn.bonoon.kernel.support.models.Item;
import cn.bonoon.kernel.support.models.Node;
import cn.bonoon.kernel.support.models.Page;

/**
 * <pre>
 * Finder是调用业务逻辑接口的一个方法创建出来的，也就是说这个时候的事务应该是已经提交或关闭；
 * 在web环境下，如果配置的由请求来管理session，则这样的方式不会出错，但这个时候如果有数据
 * 提交，则会有异常出现(Finder是查询对象，不应该出现提交数据的问题)；
 * 如果web服务器环境里没有管理session，则Finder在执行查找的时候就会出现session已经
 * 关闭的异常。
 * 
 * 最好的做不是在Finder的实现类里调用业务逻辑，而不是直接把{@link javax.persistence.EntityManager EntityManager}对象给Finder使用
 * </pre>
 * @author jackson
 *
 */
public interface Finder {

	String DEFAULT_SELECT_FIELDS = "x.id,x.name";
	/**
	 * 可以自己指定查询结果的返回字段；如："x.id,x.name" 等
	 * @param fields
	 * @return
	 * @throws Exception 
	 */
	List<Object> getList(String selectFields) throws Exception;
	
	List<Object> getList() throws Exception;
	
	Page getPage() throws Exception;
	
	void setHandler(FinderHandler handler);
	
	/**
	 * 默认的取{@link Item}数据，默认表达式："x.id,x.name"
	 * @return
	 */
	List<Item> items();
	
	/**
	 * 自定义查询的表达式，默认情况是："x.id,x.name"
	 * @param selectFields
	 * @return
	 */
	List<Item> items(String selectFields);
	
	List<Item> items(ItemSelectedFilter filter);
	
	List<Item> items(String selectFields, ItemSelectedFilter filter);
	
	List<Node> nodes();
	
	List<Node> nodes(String selectFields);
	
	List<Node> nodes(ItemSelectedFilter filter);
	
	List<Node> nodes(String selectFields, ItemSelectedFilter filter);
	
	List<AjaxNode> ajaxNodes();
	
	List<AjaxNode> ajaxNodes(String selectFields);
	
	List<AjaxNode> ajaxNodes(ItemSelectedFilter filter);
	
	List<AjaxNode> ajaxNodes(String selectFields, ItemSelectedFilter filter);
	
	/**
	 * 不带参数的表达式，可以直接使用查询语句
	 * <p>
	 * 注意：自定义的查询条件表达式，需要使用完整的表达式;
	 * 如：
	 * x.size=2
	 * </p>
	 * 
	 * <font color='red'>注意：在最开始不需要使用"and"操作符，但可以使用多个表达式的结合</font>
	 * @param and
	 * @return
	 */
	Finder and(String and);
	/**
	 * 
	 * <font color='red'>注意：在最开始不需要使用"and"操作符，但可以使用多个表达式的结合</font>
	 * @param and
	 * @param para
	 * @return
	 */
	Finder and(String and, Object para);
	/**
	 * 
	 * <font color='red'>注意：在最开始不需要使用"and"操作符，但可以使用多个表达式的结合</font>
	 * @param and
	 * @param para
	 * @param para2
	 * @return
	 */
	Finder and(String and, Object para, Object para2);
	/**
	 * 
	 * <font color='red'>注意：在最开始不需要使用"and"操作符，但可以使用多个表达式的结合</font>
	 * @param and
	 * @param paras
	 * @return
	 */
	Finder and(String and, Object...paras);
	
	/**
	 * 
	 * <font color='red'>注意：在最开始不需要使用"or"操作符，但可以使用多个表达式的结合</font>
	 * @param or
	 * @return
	 */
	Finder or(String or);
	/**
	 * 
	 * <font color='red'>注意：在最开始不需要使用"or"操作符，但可以使用多个表达式的结合</font>
	 * @param or
	 * @param para
	 * @return
	 */
	Finder or(String or, Object para);
	
	/** <font color='red'>注意：在最开始不需要使用"or"操作符，但可以使用多个表达式的结合</font> */
	Finder or(String or, Object...paras);
	
	Finder order(String sn, String on);

	
	List<Object> tryLoadRoot() throws Exception;
	
	List<Object> tryLoadChildren(Long id) throws Exception;
}
